package cn.colins.raft.rpc.domin;


import cn.colins.raft.enity.*;
import cn.colins.raft.exception.RaftRunException;
import cn.colins.raft.rpc.enums.MsgTypeEnum;
import cn.colins.raft.utils.EncryptUtil;
import cn.colins.raft.utils.HessianUtils;
import cn.hutool.core.date.DateUtil;

import java.io.Serializable;

/**
 * @Description
 * @Author czl
 * @Version V1.0.0
 * @Since 1.0
 * @Date 2023/6/12
 */
public class RpcRemoteMsg<T> implements Serializable {
    // 消息体开头标记
    private short startSign = (short) 0x01F1;
    // 时间戳
    private int timeStamp;
    // 区分是请求还是响应  0：请求  1：响应
    private short msgType;
    // 加密序列号 随机选择一个秘钥 对称性加密
    private short encryptSequence;
    // 消息体长度
    private int contentLength;
    // 消息体
    private byte[] content;

    public RpcRemoteMsg(T request) {
        this.timeStamp = (int) (DateUtil.current() / 1000);
        this.encryptSequence = EncryptUtil.getRandomKeyIndex();

        if(request instanceof RequestVoteResult){
            this.msgType = MsgTypeEnum.VOTE_RPC_RESULT.getCode();
        }else if (request instanceof RequestVoteRPC){
            this.msgType = MsgTypeEnum.VOTE_RPC.getCode();
        }else if(request instanceof HeartBeatRequest){
            this.msgType = MsgTypeEnum.HEART_BEAT.getCode();
        }else if(request instanceof HeartBeatResult){
            this.msgType = MsgTypeEnum.HEART_BEAT_RESULT.getCode();
        }else if(request instanceof AppendEntriesCommit){
            this.msgType = MsgTypeEnum.LOG_COMMIT.getCode();
        }else if(request instanceof AppendEntriesPreCommit){
            this.msgType = MsgTypeEnum.LOG_PRE_COMMIT.getCode();
        }else if(request instanceof AppendEntriesPreCommitResult){
            this.msgType = MsgTypeEnum.LOG_PRE_COMMIT_RESULT.getCode();
        }else if(request instanceof ClientRequest){
            this.msgType = MsgTypeEnum.CLIENT_REQUEST.getCode();
            // 因为日志设计那里设计死了大小，这里判断一下
            if(((ClientRequest) request).getCommand().getBytes().length>476){
                throw new RaftRunException("命令长度不得超过476个字节");
            }
        }else if(request instanceof ClientResponse){
            this.msgType = MsgTypeEnum.CLIENT_REQUEST_RESULT.getCode();
        }else if(request instanceof LogIndexPull){
            this.msgType = MsgTypeEnum.LOG_PULL_REQUEST.getCode();
        }else if(request instanceof LogIndexPullResult){
            this.msgType = MsgTypeEnum.LOG_PULL_REQUEST_RESULT.getCode();
        }

        this.content = EncryptUtil.encryptMsg(this.encryptSequence, HessianUtils.toBytes(request));
        this.contentLength = this.content.length;
    }


    public int getContentLength() {
        return contentLength;
    }

    public void setContentLength(int contentLength) {
        this.contentLength = contentLength;
    }

    public void setContent(byte[] content) {
        this.content = content;
    }

    public byte[] getContent() {
        return content;
    }

    public int getTimeStamp() {
        return timeStamp;
    }

    public short getEncryptSequence() {
        return encryptSequence;
    }

    public short getMsgType() {
        return msgType;
    }

    public short getStartSign() {
        return startSign;
    }


}
